﻿using VectorMath;
using System.Collections.Generic;

namespace FluidSystem
{
    public class FluidSetElement
    {
        public FluidSetElement(bool floating, int x, int y, int z)
        {
            IsFloating = floating;
            Depth = 1;
            CellID = new Pnt3I(x, y, z);
        }

        public FluidSetElement Parent;
        public bool IsFloating;
        public int Depth;

        public Pnt3I CellID;

    }

    public class FluidSet
    {
        public Dictionary<Pnt3I, FluidSetElement> indicesToCells = new Dictionary<Pnt3I, FluidSetElement>();

        public void Union(Pnt3I a, Pnt3I b)
        {
            //handle neighbors outside the simulation world and those without fluid
            if (!indicesToCells.ContainsKey(a) || !indicesToCells.ContainsKey(b))
                return;

            FluidSetElement aParent = Find(a);
            FluidSetElement bParent = Find(b);

            if (aParent.Depth > bParent.Depth)
            {
                bParent.Parent = aParent;
                aParent.IsFloating &= bParent.IsFloating;
            }
            else if (bParent.Depth > aParent.Depth)
            {
                aParent.Parent = bParent;
                bParent.IsFloating &= aParent.IsFloating;
            }
            else
            {
                if (aParent.Equals(bParent))
                {
                    ;
                }
                else
                {
                    aParent.Parent = bParent;
                    bParent.IsFloating &= aParent.IsFloating;
                    bParent.Depth += 1;
                }
            }
        }

        public FluidSetElement Find(Pnt3I a)
        {
            if (indicesToCells[a].Parent == null)
            {
                return indicesToCells[a];
            }
            else
            {
                indicesToCells[a].Parent = Find(indicesToCells[a].Parent.CellID); //path compression
                return indicesToCells[a].Parent;
            }
        }

    }

}
